import { Link } from '@brillout/docpress'
import { UiFrameworkExtension, ConfigSpec } from '../../components'

<ConfigSpec
  env={<>client, and server if <Link href="/ssr"><code>ssr: true</code></Link></>}
  global={null}
/>

The `+Page` setting determines the root component of the page.

With JSX (React/Solid):

```tsx
// /pages/index/+Page.tsx

export { Page }
/* Or:
export default Page
*/

function Page() {
  return (
    <>
      <h1>Hi</h1>
      <p>Hello World</p>
    </>
  )
}
```

With Vue:
```vue
<!-- /pages/index/+Page.vue -->

<template>
  <h1>Hi</h1>
  <p>Hello World</p>
</template>
```

What happens with the `Page` value is determined by the <UiFrameworkExtension />.

> Instead of using <UiFrameworkExtension name noLink />, you can also manually integrate the <Link href="/ui-frameworks">UI framework</Link> yourself, see <Link href="#without-vike-react-vue-solid" />.



## `pageContext`

You can access <Link href="/pageContext">the `pageContext` object</Link> by using <Link href="/usePageContext">`usePageContext()`</Link>.

```tsx
// /pages/+Page.tsx

import { usePageContext } from 'vike-react/usePageContext' // or vike-{vue,solid}

export function Page() {
  const pageContext = usePageContext()
  // ...
}
```


## Without `vike-{react,vue,solid}`

Vike itself never uses the `Page` value: it just makes the value available at `pageContext.Page`.
The `pageContext.Page` value is typically used by the <Link href="/onRenderHtml">`onRenderHtml()`</Link> and <Link href="/onRenderClient">`onRenderClient()`</Link> hooks: these two hooks essentially determine how the `Page` value is rendered to HTML and the [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model).

The <UiFrameworkExtension /> implements the `onRenderHtml()` and `onRenderClient()` hooks, so that you don't have to implement them: everything just works like a regular frontend framework such as Next.js or Nuxt.

Instead of using <UiFrameworkExtension name noLink />, you can integrate your favorite UI framework yourself: you then have complete control over the UI framework integration.

Here is a minimal example of manually integrating a UI framework:

```tsx
// /pages/hello/+Page.ts
// Environment: client and server (configurable)

export { Page }

function Page() {
  // Here we export a JSX component, but we can export anything we want since Vike doesn't
  // do anything with `Page`: it just makes it available at `pageContext.Page`.
  return <>Hello World</>
}
```

> You can configure in which environment the `Page` value is loaded by using <Link href="/meta">`meta`</Link>.

```ts
// /renderer/+onRenderHtml.ts
// Environment: server

export { onRenderHtml }

import type { PageContextServer } from 'vike/types'
import { escapeInject, dangerouslySkipEscape } from 'vike/server'
import { renderToHtml } from 'my-favorite-ui-framework/server'

async function onRenderHtml(pageContext: PageContextServer) {
  // The Page value is available at pageContext.Page
  const { Page } = pageContext
  const pageHtml = await renderToHtml(Page)

  return escapeInject`<html>
    <body>
      <div id="root">
        ${dangerouslySkipEscape(pageHtml)}
      </div>
    </body>
  </html>`
}
```

```ts
// /renderer/+onRenderClient.ts
// Environment: client

export { onRenderClient }

import { hydrateDom } from 'my-favorite-ui-framework/client'
import type { PageContextClient } from 'vike/types'

async function onRenderClient(pageContext: PageContextClient) {
  // pageContext.Page is also available in the browser
  const { Page } = pageContext
  await hydrateDom(Page, document.getElementById('root'))
}
```


## See also

- <Link href="/Layout" />
- <Link href="/Wrapper" />
- <Link href="/settings" />
